import 'dart:convert';

import 'package:flutter_book/config/application.dart';
import 'package:flutter_book/data/model/book_model.dart';

import 'db_helper.dart';

class CollectBookHelper {
  static CollectBookHelper? _helper;

  static CollectBookHelper init() {
    if (_helper == null) {
      _helper = CollectBookHelper();
    }
    return _helper!;
  }

  static String bookModelTableName = "book_collect_table";
  static String bookModelBookId = "book_id";
  static String bookModelJson = "content_json";
  static String bookModelAddTime = "add_time";

  Future<bool> update(BookModel? dto) async {
    if (dto == null || dto.id == null) {
      return false;
    }
    if (await isHave(dto.id!)) {
      return await _update(dto);
    } else {
      return await _insert(dto);
    }
  }

  Future<bool> switchCollect(BookModel? dto) async {
    if (dto == null || dto.id == null) {
      return false;
    }
    if (await isHave(dto.id!)) {
      await remove(dto);
      Application.collectBookController?.removeItem(dto);
      return true;
    } else {
      bool isComplete = await _insert(dto);
      if (isComplete) Application.collectBookController?.addItem(dto);
      return isComplete;
    }
  }

  Future<bool> _insert(BookModel? dto) async {
    if (dto == null) {
      return false;
    }
    var result = await DBHelper.instance.db.insert(bookModelTableName, toMap(dto));
    return result > 0;
  }

  Future<bool> _update(BookModel? dto) async {
    if (dto == null) {
      return false;
    }
    var result =
        await DBHelper.instance.db.update(bookModelTableName, toMap(dto), where: "$bookModelBookId = '${dto.id}'");
    return result > 0;
  }

  Future<List<BookModel>> queryAll() async {
    List<BookModel> list = [];
    var result = await DBHelper.instance.db.query(bookModelTableName, orderBy: "$bookModelAddTime desc");
    for (Map<String, dynamic> map in result) {
      list.add(BookModel.fromJson(json.decode(map[bookModelJson])));
    }
    return list;
  }

  Future<bool> isHave(String id) async {
    List<Map<String, dynamic>> result = [];
    result = await DBHelper.instance.db.query(bookModelTableName, where: "$bookModelBookId = '$id'");
    return result.length > 0;
  }

  Future<void> clearAll() async {
    await DBHelper.instance.db.delete(bookModelTableName);
  }

  Future<void> remove(BookModel dto) async {
    await DBHelper.instance.db.delete(bookModelTableName, where: "$bookModelBookId = '${dto.id}'");
  }

  Map<String, Object?> toMap(BookModel dto) {
    Map<String, Object?> map = Map();
    map[bookModelBookId] = dto.id;
    map[bookModelJson] = jsonEncode(dto.toJson());
    map[bookModelAddTime] = new DateTime.now().millisecondsSinceEpoch;
    return map;
  }
}
